package com.ssh.dao.impl;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.ssh.dao.GenericDAO;


/**
 * 通用DAO 实现
 * 
 * @author wancg
 * 
 */
public class GenericDAOImpl<T> extends HibernateDaoSupport implements GenericDAO<T> {

	private String className;

	public GenericDAOImpl(String className) {
		this.className = className;
	}

	@Override
	public void save(T obj) {
		// this.getSession(); // 使用原始 hibernate编程方式
		// this.getHibernateTemplate(); // 使用 Spring 提供模板工具类
		this.getHibernateTemplate().save(obj);
	}

	@Override
	public void update(T obj) {
		this.getHibernateTemplate().update(obj);
	}

	@Override
	public void delete(T obj) {
		this.getHibernateTemplate().delete(obj);
	}

	@Override
	// DbUitls new BeanHandler<User>(User.class);
	public T findById(Serializable id) {
		Class<?> clazz = null;
		try {
			clazz = Class.forName(className);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return (T) this.getHibernateTemplate().get(clazz, id);
	}

	@Override
	public List<T> findAll() {
		return  (List<T>) this.getHibernateTemplate().find("from " + className);// 注意空格
	}

	@Override
	public List<T> findByNamedQuery(String queryName, Object... values) {
		return  (List<T>) this.getHibernateTemplate().findByNamedQuery(queryName, values);
	}

	@Override
	public List<T> findByCriteria(DetachedCriteria detachedCriteria) {
		return  (List<T>) this.getHibernateTemplate().findByCriteria(detachedCriteria);
	}

	@Override
	public List<T> getlListForPage(final String strQuery,final int off,final int length){
		return (List<T>) getHibernateTemplate().executeFind(new HibernateCallback(){
			public Object  doInHibernate(Session session) throws HibernateException,SQLException{
			Query query=session.createQuery(strQuery);
			query.setFirstResult(off);
			query.setMaxResults(length);
			List<T> list = query.list();
			return list;
			}
		});
	}
	
	@Override
	public <T> int batchSave(final List<T> list,final int BATCH_MAX_ROW) {
	    int affectedRow = (Integer) getHibernateTemplate().execute(
	        new HibernateCallback() {
	            public Object doInHibernate(Session session)
	                   throws HibernateException, SQLException {
	            	int i=0;
	                for (T t:list) {
	                	i++;
	                    session.save(t);
	                    if (i % BATCH_MAX_ROW == 0) {
	                        session.flush();
	                        session.clear();
	                    }
	                }
	                session.flush();
	                session.clear();
	                return list.size();
	            }
	    });
	    return affectedRow;
	}

	@Override
	public List<T> getlListForSQL(final String sql) {
		return (List<T>) getHibernateTemplate().executeFind(new HibernateCallback(){
			public Object  doInHibernate(Session session) throws HibernateException,SQLException{
			SQLQuery createSQLQuery = session.createSQLQuery(sql);
			List<T> list = createSQLQuery.list();
			return list;
			}
		});
	}
	
	@Override
	public int getlListForSQL2(final String sql) {
		return  getHibernateTemplate().execute(new HibernateCallback(){
			public Object  doInHibernate(Session session) throws HibernateException,SQLException{
			int createSQLQuery = session.createSQLQuery(sql).executeUpdate();
//			List<T> list = createSQLQuery.list();
			return createSQLQuery;
			}
		});
	}
}
